﻿using B.S.Databasic.Api.Read.Application.Command.Account;
using B.S.Databasic.Domain.RBAC;
using B.S.Databasic.ErrorCode;
using B.S.Databasic.Infrastructure.Interface;
using Humanizer;
using MediatR;
using Mono.TextTemplating;
using System.Data;

namespace B.S.Databasic.Api.Read.Application.Handler.Account
{
    public class GetAccountPageHandler : IRequestHandler<GetAccountPageCommand, ApiPageing<AccountDTO>>
    {
        private readonly IBaseRepository<AccountModel> accountRepo;
        private readonly IBaseRepository<RoleModel> roleRepo;
        private readonly IBaseRepository<AccountRoleModel> accountroleRepo;

        public GetAccountPageHandler(IBaseRepository<AccountModel> accountRepo, IBaseRepository<RoleModel> roleRepo, IBaseRepository<AccountRoleModel> accountroleRepo)
        {
            this.accountRepo = accountRepo;
            this.roleRepo = roleRepo;
            this.accountroleRepo = accountroleRepo;
        }

        public async Task<ApiPageing<AccountDTO>> Handle(GetAccountPageCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiPageing<AccountDTO>();
            try
            {
                var acc = accountRepo.GetAll().Where(x => !x.IsDeleted);
                if (!string.IsNullOrEmpty(request.Name))
                {
                    acc = acc.Where(x => x.Name.Contains(request.Name));
                }
                var linq = from a in acc
                           join b in accountroleRepo.GetAll().Where(x => !x.IsDeleted) on a.Id equals b.AccountId into ab
                           from b in ab.DefaultIfEmpty()
                           join c in roleRepo.GetAll().Where(x => !x.IsDeleted) on b.RoleId equals c.Id into ac
                           from c in ac.DefaultIfEmpty()
                           select new { a, b, c };
                var grouped = linq
                    .GroupBy(x => x.a)
                    .Select(c => new AccountDTO
                    {
                        Id = c.Key.Id,
                        Name = c.Key.Name,
                        Pwd = c.Key.Pwd,
                        RealName = c.Key.RealName,
                        IsState = c.Key.IsState,
                        CreateTime = c.Key.CreateTime,
                        RoleIds = c.Where(x => x.b != null).Select(x => x.b!.RoleId).ToList(),
                        RoleName = c.Where(x => x.c != null).Select(x => x.c.RoleName).ToList()
                    });
                var datas = grouped.OrderByDescending(x => x.CreateTime).Skip((request.Index - 1) * request.Size).Take(request.Size).ToList();
                res.TotaCount = datas.Count;
                res.TotaPage = (int)Math.Ceiling(res.TotaCount * 1.0 / request.Size);
                res.PageData = datas;
                res.Msg = "查询用户列表成功!";
                res.Code = ApiEnum.Success;
                return await Task.FromResult(res);
            }
            catch (Exception ex)
            {
                res.Msg = "查询用户列表异常!" + ex.Message;
                res.Code = ApiEnum.Error;
                return await Task.FromResult(res);
            }
        }
    }
}
